import 'dart:io';

import 'package:deb_packer/src/cli_logger.dart';

import 'config.dart';

// yaml 配置转化类
class YamlHandler {
  // control 字段
  String? controlPath;
  late ControlContent controlContent;
  // dirs 字段内容
  late DirsContent dirsContent;
  Map<String, String>? dirs;
  // DEBIAN 文件路径
  Map<String, String> debianPathMap = {};

  final debainFiles = ['postinst', 'preinst', 'rules', 'postrm', 'prerm'];

  YamlHandler();

  void setDebConfig(Map<String, dynamic> yamlMap) {
    _setDEBIAN(yamlMap);
    _setDirs(yamlMap['dirs']);
  }

  void _setDEBIAN(Map<String, dynamic> yamlMap) {
    _setControl(yamlMap['control']);

    for (var path in debainFiles) {
      if (yamlMap[path] != null) {
        if (yamlMap[path] is String) {
          // 是文件路径
          var file = File(yamlMap[path]);
          if (!file.existsSync()) {
            CliLogger.error("Your '$path' path in yaml file does not exist.");
            exit(1);
          } else {
            debianPathMap[path] = yamlMap[path];
          }
        } else {
          // 不是文件路径
          CliLogger.error("Your '$path' section in yaml file is not valid.");
          exit(1);
        }
      }
    }
  }

  void _setDirs(dynamic dirsSection) {
    if (dirsSection == null) {
      CliLogger.warning("Your yaml file does not contain a 'dirs' section.");
      return;
    } else if (dirsSection is String) {
      // dirs 字段为文件路径，判断是否为文件夹
      var dir = Directory(dirsSection);
      if (!dir.existsSync()) {
        CliLogger.error("Your 'dirs' path in yaml file does not exist.");
        exit(1);
      }

      var fileList = dir.listSync();
      if (fileList.isEmpty) {
        // dirs 所指向文件夹为空
        CliLogger.error("Your 'dirs' path in yaml file is empty.");
        exit(1);
      } else {
        print('fileList $fileList');
      }
    } else if (dirsSection is Map<dynamic, dynamic>) {
      // dirs 字段为 Map
      dirsContent = DirsContent(dirsSection);
    } else {
      CliLogger.error("Your 'dirs' section in yaml file is not valid.");
      exit(1);
    }
  }

  /// 设置YAML配置的 control 文件部分。
  ///
  /// 该函数接受一个动态的控制部分，可以是字符串（表示文件路径）或Map（包含 control 文件内容）。
  /// 如果控制部分是字符串，则读取文件内容并解析为Map。如果控制部分是Map，则直接使用。
  /// 如果控制部分既不是字符串也不是Map，则记录错误并退出程序。
  /// 解析后的控制内容存储在controlContent变量中。
  ///
  /// @param controlSection YAML配置的 control 字段。
  void _setControl(dynamic controlSection) {
    var controlObj = {};
    if (controlSection is String) {
      // control 字段为文件路径
      var controlFile = File(controlSection);
      var content = controlFile.readAsLinesSync();
      if (content.isNotEmpty) {
        for (var line in content) {
          if (line.isNotEmpty) {
            var key = line.split(':')[0];
            var value = line.split(':')[1];
            controlObj[key] = value;
          }
        }
      } else {
        // control 文件内容为空
        CliLogger.error("The yaml file at $controlSection is empty .");
        exit(1);
      }
    } else if (controlSection is Map<String, dynamic>) {
      // control 字段下写着 control 文件内容
      controlObj = controlSection;
    } else {
      CliLogger.error(
          "Your yaml file does not contain a valid 'control' section or a 'control' file path.");
      exit(1);
    }

    controlContent = ControlContent(controlObj as Map<String, dynamic>);
  }

  void _copyDebianFiles(String buildDist) {
    final debianDir = Directory('$buildDist/DEBIAN');
    if (!debianDir.existsSync()) {
      debianDir.createSync(recursive: true);
    }
    for (final entry in debianPathMap.entries) {
      File file = File(entry.value);
      file.copySync('$buildDist/DEBIAN/${entry.key}');
    }
  }

  void build(String buildDist) async {
    CliLogger.info("Building...");
    try {
      controlContent.build(buildDist);
      dirsContent.build(buildDist);
      _copyDebianFiles(buildDist);
    } catch (e) {
      CliLogger.error("Build failed: $e");
      exit(1);
    }

    CliLogger.success('Building successful');
  }
}
